import Axios from "axios";
import store from "@/store";
import { ElMessageBox, ElMessage } from "element-plus";
import { getToken } from "@/service/cookieFun";

const statusMessage: any = {
  200: "服务器成功返回请求的数据。",
  201: "新建或修改数据成功。",
  202: "一个请求已经进入后台排队（异步任务）。",
  204: "删除数据成功。",
  400: "发出的请求有错误，服务器没有进行新建或修改数据的操作。",
  401: "用户没有权限（令牌、用户名、密码错误）。",
  403: "用户得到授权，但是访问是被禁止的。",
  404: "发出的请求针对的是不存在的记录，服务器没有进行操作。",
  405: "请求方法不被允许。",
  406: "请求的格式不可得。",
  410: "请求的资源被永久删除，且不会再得到的。",
  422: "当创建一个对象时，发生一个验证错误。",
  429: "请求太频繁，请1分钟后再试！",
  500: "服务器发生错误，请检查服务器。",
  502: "网关错误。",
  503: "服务不可用，服务器暂时过载或维护。",
  504: "网关超时。",
};

const tansParams = (params) => {
  let result = "";
  for (const propName of Object.keys(params)) {
    const value = params[propName];
    var part = encodeURIComponent(propName) + "=";
    if (value !== null && typeof value !== "undefined") {
      if (typeof value === "object") {
        for (const key of Object.keys(value)) {
          if (value[key] !== null && typeof value[key] !== "undefined") {
            let params = propName + "[" + key + "]";
            var subPart = encodeURIComponent(params) + "=";
            result += subPart + encodeURIComponent(value[key]) + "&";
          }
        }
      } else {
        result += part + encodeURIComponent(value) + "&";
      }
    }
  }
  return result;
}

// 创建axios实例
const request = Axios.create({
  // 根据环境自动选择API地址
  baseURL: import.meta.env.VITE_API_BASE,
  // 超时（请求超过10秒为超时）
  timeout: 10000,
});

// 前置拦截器（发起请求之前的拦截）
request.interceptors.request.use(
  config => {
    config.headers["Content-Type"] = config.headers["Content-Type"]
      ? config.headers["Content-Type"]
      : "application/json";
    // 根据后端配置携带token的请求头
    config.headers["Cookie"] = getToken();

    // get请求映射params参数
    if (config.method === "get" && config.params) {
      let url = config.url + "?" + tansParams(config.params);
      url = url.slice(0, -1);
      config.params = {};
      config.url = url;
    }
    return config;
  },
  error => {
    Promise.reject(error);
  }
);

// 后置拦截器（获取到响应时的拦截）
request.interceptors.response.use(
  res => {
    // 状态码（默认成功状态）
    const { status, message } = res.data;

    if (status === 200) {
      return res.data;
    } else if (status === 401) {
      // 401 token失效
      ElMessageBox.confirm(statusMessage[status], "系统提示", {
        type: "warning",
        showCancelButton: false,
        cancelButtonText: "取消",
        showConfirmButton: true,
        confirmButtonText: "确定"
      })
        .then(() => {
          // 确定
          store.dispatch("LogOut");
        })
        .catch(() => {
          // 取消
          store.dispatch("LogOut");
        });
    } else {
      // 状态码非200
      ElMessage({
        message: message,
        type: "error",
        duration: 5 * 1000
      });
      return res.data;
    }
  },
  e => {
    // 不报错白名单
    const whiteList = [];
    let whiteListFlag = false;
    for (let i = 0; i < whiteList.length; i++) {
      if (e.config.url.indexOf(whiteList[i]) != -1) {
        whiteListFlag = true;
        break;
      }
    }
    // 接口请求报错
    const { status, message } = e;
    // 判断是否是白名单中的接口（不是白名单中的接口，抛出错误）
    if(!whiteListFlag) {
      // 有状态码提示
      if(statusMessage[status]) {
        if(status === 401) {
          // 401 token失效
          ElMessageBox.confirm(statusMessage[status], "系统提示", {
            type: "warning",
            showCancelButton: false,
            cancelButtonText: "取消",
            showConfirmButton: true,
            confirmButtonText: "确定"
          })
            .then(() => {
              // 确定
              store.dispatch("LogOut");
            })
            .catch(() => {
              // 取消
              store.dispatch("LogOut");
            });
        } else {
          ElMessage({
            message: `code ${status}: ${statusMessage[status]}`,
            type: "error",
            duration: 5 * 1000
          });
        }
      } else {
        // 无状态码提示
        ElMessage({
          message: `code ${status}: ${message}`,
          type: "error",
          duration: 5 * 1000
        });
      }
    }
    return Promise.reject(e);
  }
);

export default request;
